JSON是當前網路上面傳遞key-value pair蠻流行的資料格式,如果想要在Postgres資料庫上面存放JSON的資料型態的話,Postgres有提供一些適合表示JSON的資料型態:
1.hstore:單純的key-value格式,功能陽春,無法呈現JSON物件的巢狀結構
2.JSON:可以理解成以文字的形式記錄JSON
3.JSONB:為JSON最佳化的資料格式,可以支援index以及JSON物件巢狀結構的表示
參考資料:
https://www.pg4e.com/lectures/06-JSON.php
將JSON的資料插入jsonb欄位裡面,可以透過將字串轉型成jsonb的方式。
INSERT INTO swapi (body)
SELECT ('{ "type": "Neon", "series": "24 Hours of Lemons", "number": ' || generate_series(1000,5000) || '}')::jsonb;
JSONB的查詢,可以透過'->>' operator取得json中特定key的欄位文字(資料型態為text),若是要取出數字需要將->> operator包進括號然後轉型成數字。
例子:
透過json欄位的name屬性之數值來篩選資料
SELECT COUNT(*) FROM jtrack WHERE body->>'name' = 'Summer Nights';
如果要查找jsonb欄位的內容是否包含某個key-value pair,可以透過"@>"operator
SELECT COUNT(*) FROM jtrack WHERE body @> '{"name": "Summer Nights"}';
單純查找jsonb欄位是否有特定的key,可以使用"?"operatpor
--測試"favorite"key是否存在json欄位中
SELECT COUNT(*) FROM jtrack WHERE body ? 'favorite';
如果要將額外的key加入json欄位的紀錄,可以透過"||"operator來達成
UPDATE jtrack SET body = body || '{"favorite": "yes"}' WHERE (body->'count')::int > 200;
至於更新jsonb欄位中key的數值,可以使用jsonb_update的function
UPDATE jtrack SET body = jsonb_set(body, '{ count }', ( (body->>'count')::int + 1 )::text::jsonb )
WHERE body->>'name' = 'Summer Nights';
jsonb欄位可以使用b-tree或是GIN index來檢索內容。
B-tree index可以用來對json的某一支key做索引,GIN index可以用來快速檢查jsonb欄位是否存在某個key,而透過GIN index在jsonb_path_ops上面建立索引可以幫助掃描任意的key_value pair組合(上面提過的@> operator)。
CREATE INDEX jtrack_btree ON jtrack USING BTREE ((body->>'name'));
CREATE INDEX jtrack_gin ON jtrack USING gin (body);
CREATE INDEX jtrack_gin_path_ops ON jtrack USING gin (body jsonb_path_ops);